package com.zwj.service.impl;

import com.zwj.config.FileProperties;
import com.zwj.enums.ErrorEnum;
import com.zwj.interceptor.BizException;
import com.zwj.service.FileService;
import com.zwj.utils.FileUtils;
import com.zwj.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;

@Service
public class FileServiceImpl implements FileService {
    private final Path filePath;
    private final Path imagePath;
    @Autowired
    public FileServiceImpl(FileProperties fileProperties) {
        this.filePath = Paths.get(fileProperties.getFile()).toAbsolutePath().normalize();
        this.imagePath = Paths.get(fileProperties.getImage()).toAbsolutePath().normalize();
    }

    @Override
    public Result upload(MultipartFile file) {
        if (file == null) {
            return Result.error("上传文件为空");
        }
        String dirPath = FileUtils.mkdirs(new ApplicationHome(getClass()));
        String fileName = file.getOriginalFilename();
        String[] fn = fileName.split("\\.");
        String fileExtension = fn[1];
        System.out.println("后缀:" + fileExtension);
        System.out.println(!FileUtils.isFileExtension(fileExtension));
        if (!FileUtils.isFileExtension(fileExtension)) return Result.error("上传文件失败，含有不被接受的文件名");
        String name = "";
        int i;
        System.out.println("过");
        for (i = 0; i < 3; i += 1) {
            name = FileUtils.getFileName();
            if (!(new File(dirPath + name + "." + fileExtension)).exists()) {
                break;
            }
        }
        System.out.println("i:" + i);
        if (i >= 3) {
            return Result.error("上传文件失败，含有不被接收的文件名");
        }
        try {
            //将文件写入磁盘
            file.transferTo(new File(dirPath + name + "." + fileExtension));
            fileName = name + "." + fileExtension;
            return Result.success(fileName);
        } catch (IOException e) {

        }
        return Result.error("上传文件失败");
    }

    @Override
    public void download(String fileName, HttpServletResponse response) {
        if (fileName == null || fileName.equals("")) {
            return;
        }
        String dirPath = FileUtils.mkdirs(new ApplicationHome(getClass()));
        try {
            // path是指想要下载的文件的路径
            File file = new File(dirPath + fileName);
            //文件目录是否存在
            if (!file.exists()) {
                return;
            }
            // 将文件写入输入流
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStream fis = new BufferedInputStream(fileInputStream);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();

            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
//            if (fileName == null || fileName.equals("")) {
//                fileName = path;
//            }
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            // 告知浏览器文件的大小
            response.addHeader("Content-Length", "" + file.length());
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            outputStream.write(buffer);
            outputStream.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public Result uploadFile(MultipartFile file) {
        try {
            if(file.isEmpty()){
                return Result.error("上传文件为空");
            }
            String fileName = file.getOriginalFilename();
            String[] fn = fileName.split("\\.");
            if(fn.length<2){
                return Result.error("文件名格式不符合");
            }
            String fileExtension = fn[fn.length-1];
            System.out.println("后缀:" + fileExtension);
            System.out.println(!FileUtils.isFileExtension(fileExtension));
            if (!FileUtils.isFileExtension(fileExtension)) return Result.error("上传文件失败，含有不被接受的文件名");
            String os = System.getProperty("os.name");
            File fileRealPath;   //文件存放地址
            if (os.toLowerCase().startsWith("win")) {  //windows系统
                fileRealPath = new File(FileUtils.mkdirs(new ApplicationHome(getClass())));
            }else{//linux系统
                fileRealPath = new File(filePath.toUri());
                //判断文件夹是否存在
                if(!fileRealPath.exists()){
                    //不存在，创建
                    fileRealPath.mkdirs();
                }
//                fileRealPath = new File(FileUtils.mkdirshead(new ApplicationHome(getClass()),"/file/"));
            }
            String name = null;
            File resultPath =null;
            int i;
            for (i = 0; i < 3; i += 1) {
                //获取文件名称
                name = FileUtils.getFileName();
                //创建文件存放地址
                resultPath = new File(fileRealPath+"/"+name+"."+fileExtension);
                if (!resultPath.exists()){
                    break;
                }
            }
            if (i >= 3) {
                return Result.error("上传文件失败，失败原因生成文件名失败");
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            file.transferTo(resultPath);
            System.out.println("absolutePath:"+fileRealPath.getCanonicalPath());
            System.out.println("resultPath:"+resultPath.getCanonicalPath());
            return Result.success(resultPath.getCanonicalPath()+name+"."+fileExtension);
        }catch (Exception e){
            return Result.error("上传文件失败");
        }
    }

    @Override
    public ResponseEntity<Resource> downloadFile(String fileName, HttpServletRequest request) throws UnsupportedEncodingException {
        System.out.println(fileName+"====================================================");
        if (fileName == null || fileName.equals("")) {
            throw new BizException(ErrorEnum.BODY_NOT_MATCH.getResultCode(),"文件名为空");
        }
//        String[] fn = fileName.split("\\.");
//        if (fn.length<2){
//            throw new BizException(ErrorEnum.BODY_NOT_MATCH.getResultCode(),"文件名格式错误");
//        }
//        String fileExtension = fn[1];
        Path path = filePath.resolve(fileName).normalize();
        System.out.println(path+"---------------------------------------------------");
        Resource resource = null;
        try {
             resource = new UrlResource(path.toUri());
            System.out.println(path.toUri()+"---------------------------------------------------");
            if (!resource.exists()) {
                throw new BizException(ErrorEnum.BODY_NOT_MATCH.getResultCode(),"文件找不到");
            }
        } catch (MalformedURLException e) {
            throw new BizException(ErrorEnum.BODY_NOT_MATCH.getResultCode(),"文件错误");
        }
        String contentType = null;
        try {
            System.out.println("=================================="+resource.getFile().getAbsolutePath());
            contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
        } catch (IOException e) {
            throw new BizException(ErrorEnum.BODY_NOT_MATCH.getResultCode(),"无法获取文件格式");
        }
        if (contentType == null) {
            contentType = "application/octet-stream";
        }
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(contentType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + new String(resource.getFilename().getBytes("UTF-8"),"iso-8859-1")  + "\"")
                .body(resource);
    }

    @Override
    public Result uploadImage(MultipartFile file) {
        try {
            if(file.isEmpty()){
                return Result.error("上传文件为空");
            }
            String fileName = file.getOriginalFilename();
            String[] fn = fileName.split("\\.");
            if(fn.length<2){
                return Result.error("文件名格式不符合");
            }
            String fileExtension = fn[fn.length-1];
            System.out.println("后缀:" + fileExtension);
            System.out.println(!FileUtils.isFileExtension(fileExtension));
            if (!"jpg".equals(fileExtension)&&!"png".equals(fileExtension)) return Result.error("上传文件失败，含有不被接受的文件名");
            String os = System.getProperty("os.name");
            File fileRealPath;   //文件存放地址
            if (os.toLowerCase().startsWith("win")) {  //windows系统
                fileRealPath = new File(FileUtils.mkdirshead(new ApplicationHome(getClass())));
            }else{//linux系统
                fileRealPath = new File(imagePath.toUri());
                //判断文件夹是否存在
                if(!fileRealPath.exists()){
                    //不存在，创建
                    fileRealPath.mkdirs();
                }
//                fileRealPath = new File(FileUtils.mkdirshead(new ApplicationHome(getClass()),"/image/"));
            }
            String name = null;
            File resultPath =null;
            int i;
            for (i = 0; i < 3; i += 1) {
                //获取文件名称
                name = FileUtils.getFileName();
                //创建文件存放地址
                resultPath = new File(fileRealPath+"/"+name+"."+fileExtension);
                if (!resultPath.exists()){
                    break;
                }
            }
            if (i >= 3) {
                return Result.error("上传文件失败，失败原因生成文件名失败");
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            file.transferTo(resultPath);
            System.out.println("absolutePath:"+fileRealPath.getCanonicalPath());
            System.out.println("resultPath:"+resultPath.getCanonicalPath());
            return Result.success(resultPath.getCanonicalPath()+name+"."+fileExtension);
        }catch (Exception e){
            return Result.error("上传文件失败");
        }
    }
}
